﻿using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Newtonsoft.Json;

namespace SocialApi.Instagram.Entities.Methods.Locations
{
    /// <summary>
    /// Содержит информацию о локации
    /// </summary>
    public interface ILocationMethods
    {
        /// <summary>
        /// Id локации
        /// </summary>
        [JsonProperty("id")]
        long Id { get; }

        /// <summary>
        /// Широта
        /// </summary>
        [JsonProperty("latitude")]
        double Latitude { get; }

        /// <summary>
        /// Долгота
        /// </summary>
        [JsonProperty("longitude")]
        double Longitude { get; }

        /// <summary>
        /// Название локации
        /// </summary>
        [JsonProperty("name")]
        string Name { get; }

        /// <summary>
        /// Возвращает информацию о локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        ILocationMethods Get(long locationId);

        /// <summary>
        /// Асинхронно возвращает информацию о локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        Task<ILocationMethods> GetAsync(long locationId);

        /// <summary>
        /// Возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        IEnumerable<IResult> Recent(long locationId);

        /// <summary>
        /// Возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        /// <param name="minTimeStamp">Возвращает данные после заданого промежутка времени</param>
        /// <param name="maxTimeStamp">Возвращает данные перед заданым промежутком времени</param>
        IEnumerable<IResult> Recent(long locationId, DateTime? minTimeStamp, DateTime? maxTimeStamp);

        /// <summary>
        /// Возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        /// <param name="minId">Возвращает данные перед заданым Id</param>
        /// <param name="maxId">Возвращает данные после заданного Id</param>
        IEnumerable<IResult> Recent(long locationId, int minId, int maxId);

        /// <summary>
        /// Возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        /// <param name="minId">Возвращает данные перед заданым Id</param>
        /// <param name="maxId">Возвращает данные после заданного Id</param>
        /// <param name="minTimeStamp">Возвращает данные после заданого промежутка времени</param>
        /// <param name="maxTimeStamp">Возвращает данные перед заданым промежутком времени</param>
        IEnumerable<IResult> Recent(long locationId, int minId, int maxId, DateTime? minTimeStamp, DateTime? maxTimeStamp);

        /// <summary>
        /// Асинхронно возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        Task<IEnumerable<IResult>> RecenthAsync(long locationId);

        /// <summary>
        /// Асинхронно возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        /// <param name="minTimeStamp">Возвращает данные после заданого промежутка времени</param>
        /// <param name="maxTimeStamp">Возвращает данные перед заданым промежутком времени</param>
        Task<IEnumerable<IResult>> RecenthAsync(long locationId, DateTime? minTimeStamp, DateTime? maxTimeStamp);

        /// <summary>
        /// Асинхронно возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        /// <param name="minId">Возвращает данные перед заданым Id</param>
        /// <param name="maxId">Возвращает данные после заданного Id</param>
        Task<IEnumerable<IResult>> RecenthAsync(long locationId, int minId, int maxId);

        /// <summary>
        /// Асинхронно возвращает список последних медиа из данной локации
        /// </summary>
        /// <param name="locationId">Id локации</param>
        /// <param name="minId">Возвращает данные перед заданым Id</param>
        /// <param name="maxId">Возвращает данные после заданного Id</param>
        /// <param name="minTimeStamp">Возвращает данные после заданого промежутка времени</param>
        /// <param name="maxTimeStamp">Возвращает данные перед заданым промежутком времени</param>
        Task<IEnumerable<IResult>> RecenthAsync(long locationId, int minId, int maxId, DateTime? minTimeStamp, DateTime? maxTimeStamp);

        /// <summary>
        /// Поиск местоположения по заданным географическим координатам
        /// </summary>
        /// <param name="latitude">Широта</param>
        /// <param name="longitude">Долгота</param>
        IEnumerable<ILocationMethods> Search(double latitude, double longitude);

        /// <summary>
        /// Поиск местоположения по заданным географическим координатам
        /// </summary>
        /// <param name="distance">Дистанция (от 1000 до 5000)</param>
        /// <param name="latitude">Широта</param>
        /// <param name="longitude">Долгота</param>
        IEnumerable<ILocationMethods> Search(int distance, double latitude, double longitude);

        /// <summary>
        /// Асинхронный поиск местоположения по заданным географическим координатам
        /// </summary>
        /// <param name="latitude">Широта</param>
        /// <param name="longitude">Долгота</param>
        Task<IEnumerable<ILocationMethods>> SearchAsync(double latitude, double longitude);

        /// <summary>
        /// Асинхронный поиск местоположения по заданным географическим координатам
        /// </summary>
        /// <param name="distance">Дистанция (от 1000 до 5000)</param>
        /// <param name="latitude">Широта</param>
        /// <param name="longitude">Долгота</param>
        Task<IEnumerable<ILocationMethods>> SearchAsync(int distance, double latitude, double longitude);
    }
}